今天要來說明如何在Compose中進行基本的跳換頁面的動作功能。
說是跳轉頁面,但事實上偏向Java、Kotlin中的Fragment功能類似,需要一個觸發按鈕來運作。
這邊會先從簡易的跳轉頁面開始實作說明,後面還有進階一些的跳轉撰寫方法。
這邊依照以下步驟進行新增。
圖1.
到檔案資料夾點擊滑鼠右鍵->New
->Compose
->Empty Activity
圖2.
頁面,之後進行命名後點擊Finish
即可成功建立。Navigation
的 3
大主要部分是 NavController
、 NavGraph
和 NavHost
。
這是今天跳換頁面會用到的功能。
今天會以NavHost的startDestination
、navController
參數來建成一個極簡的跳轉功能,並會搭配NavGraphBuilder.composable
來組成頁面跳轉。
NavHostController
對象,用於管理和控制導覽操作。 它負責追蹤當前的導航狀態以及執行導航操作,如 navigate
、popBackStack
等。Modifier
對象,用於定義 NavHost
的修飾符。NavHost
中的對齊方式,例如 Alignment.Center
、Alignment.TopStart
等等的排列參數。NavHost
所在的路由。 通常情況下,您不需要指定此參數,因為 NavHost
通常是根層級的,但在某些情況下,可以使用它來嵌套多個 NavHost
。Lambda
函數,用於定義當導航到新目標時應用的進入動畫。Lambda
函數,用於定義當從當前目標導航到新目標時應用的退出動畫。Lambda
函數,用於定義當從後退堆疊中的目標導航回當前目標時應用的進入動畫。Lambda
函數,用於定義當從後退堆疊中的目標導航回當前目標時應用的退出動畫。Lambda
函數,用來建立導航圖。 在這裡,您可以使用 NavGraphBuilder
物件來定義導航目標和路由之間的關係,以及每個目標的內容。以上是所有的NavHost參數說明,今天只會使用到前面兩個參數來建立簡易的跳轉功能。
@Composable
@ComposableTarget
public fun NavHost(
navController: NavHostController,
startDestination: String,
modifier: Modifier = COMPILED_CODE,
contentAlignment: Alignment = COMPILED_CODE,
route: String? = COMPILED_CODE,
enterTransition: AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition = COMPILED_CODE,
exitTransition: AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition = COMPILED_CODE,
popEnterTransition: AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition = COMPILED_CODE,
popExitTransition: AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition = COMPILED_CODE,
builder: NavGraphBuilder.() -> Unit
): Unit
這邊起始畫面為MainActivity,接著建立個跳轉頁面的方法及跳轉目的地。
NavHost(navController = navController,
startDestination = "mainActivity") {
composable("mainActivity") { GreetingBackground() }
composable("homepage") { Background() }
composable("searchActivity") { SearchBackground() }
composable("profileActivity") { ProfileBackground() }
composable("settingActivity") { SettingBackground() }
}
// 讓跳轉重複點擊只會有單次挑轉,不會有反覆恆跳的感覺出現,也就是當我們每次點擊時都會先跳回主畫面在進行跳轉,但當我們。
fun NavHostController.navigateSingleTopTo(route: String) =
this.navigate(route) { launchSingleTop = true }
@Composable
private fun BottomNavigation(modifier: Modifier = Modifier, context:Context) {
val navController = rememberNavController()
val homeBool = remember {mutableStateOf(false)}
val menuBool = remember {mutableStateOf(false)}
val searchBool = remember {mutableStateOf(false)}
val profileBool = remember {mutableStateOf(false)}
val settingBool = remember {mutableStateOf(false)}
NavHost(navController = navController,
startDestination = "mainActivity") {
composable("mainActivity") { GreetingBackground() }
composable("homepage") { Background() }
composable("searchActivity") { SearchBackground() }
composable("profileActivity") { ProfileBackground() }
composable("settingActivity") { SettingBackground() }
}
Row (modifier = Modifier.fillMaxHeight()){
NavigationBar(
//...省略
){
// Menu
NavigationBarItem(
// 判斷是否有選擇,因起始畫面為menu所以反向為true。
selected = !menuBool.value,
onClick = {
// 將其餘選項關閉,由於menu是反向所以false
false.also { menuBool.value = it }
false.also { homeBool.value = it }
false.also { searchBool.value = it }
false.also { profileBool.value = it }
false.also { settingBool.value = it }
Log.e(TAG, "SootheBottomNavigation: Home" )
// 利用建立的.navigateSingleTopTo來達到單次跳轉至指定頁面。
navController.navigateSingleTopTo("MainActivity")
Toast.makeText(context, "Home", Toast.LENGTH_SHORT).show()
},
// 其餘參數調整部分省略
)
// Home
NavigationBarItem(
// 判斷是否有選擇,因起始畫面為menu所以反向為true。
selected = homeBool.value,
onClick = {
true.also { menuBool.value = it }
true.also { homeBool.value = it }
false.also { searchBool.value = it }
false.also { profileBool.value = it }
false.also { settingBool.value = it }
Log.e(TAG, "SootheBottomNavigation: Home" )
navController.navigateSingleTopTo("homepage")
Toast.makeText(context, "Home", Toast.LENGTH_SHORT).show()
},
// 其餘參數調整部分省略
)
// Search
NavigationBarItem(
// 判斷是否有選擇,因起始畫面為menu所以反向為true。
selected = searchBool.value,
onClick = {
true.also { menuBool.value = it }
false.also { homeBool.value = it }
true.also { searchBool.value = it }
false.also { profileBool.value = it }
false.also { settingBool.value = it }
navController.navigateSingleTopTo("searchActivity")
Log.e(TAG, "SootheBottomNavigation: Search" )
Toast.makeText(context, "Search", Toast.LENGTH_SHORT).show()
}
// 其餘參數調整部分省略
)
// Profile
NavigationBarItem(
// 判斷是否有選擇,因起始畫面為menu所以反向為true。
selected = profileBool.value,
onClick = {
true.also { menuBool.value = it }
false.also { homeBool.value = it }
false.also { searchBool.value = it }
true.also { profileBool.value = it }
false.also { settingBool.value = it }
navController.navigateSingleTopTo("profileActivity")
Log.e(TAG, "SootheBottomNavigation: Account" )
Toast.makeText(context, "Account", Toast.LENGTH_SHORT).show()
}
// 其餘參數調整部分省略
)
// Setting
NavigationBarItem(
// 判斷是否有選擇,因起始畫面為menu所以反向為true。
selected = settingBool.value,
onClick = {
true.also { menuBool.value = it }
false.also { homeBool.value = it }
false.also { searchBool.value = it }
false.also { profileBool.value = it }
true.also { settingBool.value = it }
navController.navigateSingleTopTo("settingActivity")
Log.e(TAG, "SootheBottomNavigation: Settings" )
Toast.makeText(context, "Setting", Toast.LENGTH_SHORT).show()
}
// 其餘參數調整部分省略
)
}
}
}
以上是在主頁面的底部導覽條功能修改,接著就是撰寫其他跳轉後的頁面布置了,這邊就以一個去做程式碼展示,因為各自跳轉的需求不同,有不同的頁面配置。
@Composable
fun SettingsSelect() {
val context = LocalContext.current
Column (Modifier.fillMaxWidth()){
Text(text = "設定",
Modifier
.padding(10.dp)
.fillMaxWidth()
.align(Alignment.CenterHorizontally),
fontSize = MaterialTheme.typography.headlineLarge.fontSize,
fontStyle = MaterialTheme.typography.headlineLarge.fontStyle,
textAlign = MaterialTheme.typography.headlineLarge.textAlign,
color = MaterialTheme.colorScheme.onBackground)
ElevatedButton(onClick = {
Toast.makeText(context, "SelfInfo Modify!", Toast.LENGTH_SHORT).show()
},Modifier.fillMaxWidth()) {
Icon(imageVector = Icons.Default.AccountCircle,
contentDescription = null)
Text(text = "個人資料修改")
}
ElevatedButton(onClick = {
Toast.makeText(context, "Schedule", Toast.LENGTH_SHORT).show()
},Modifier.fillMaxWidth()) {
Icon(imageVector = Icons.Default.DateRange,
contentDescription = null)
Text(text = "行事曆")
}
ElevatedButton(onClick = {
Toast.makeText(context, "password reset!", Toast.LENGTH_SHORT).show()
},Modifier.fillMaxWidth()) {
Icon(imageVector = Icons.Default.Lock,
contentDescription = null)
Text(text = "密碼重製")
}
ElevatedButton(onClick = {
Toast.makeText(context, "Logout your account!", Toast.LENGTH_SHORT).show()
Log.e(TAG, "SettingsSelect: Logout your account!" )
},Modifier.fillMaxWidth()) {
Icon(imageVector = Icons.Default.ExitToApp,
contentDescription = null)
Text(text = "登出")
}
}
}
@Composable
fun SettingBackground(){
Box(modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.background)) {
Column (Modifier.padding(10.dp)){
SettingsSelect()
}
}
}
這邊展示了五個頁面橫向跳轉,並包含一個跳轉過程的截圖。
以上是今天關於Navigation的跳轉功能實作與說明,也能看到因為改了點擊的布林變數的變換,所以底下的導覽條會根據目前所在的頁面一同更改selected
參數的是否。